package com.thinkverse.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.thinkverse.user.dto.IdentityClaimRequestDTO;
import com.thinkverse.user.dto.IdentityClaimRequestDTO;
import com.thinkverse.user.dto.PagedResult;
import com.thinkverse.user.entity.IdentityClaim;
import com.thinkverse.user.entity.User;
import com.thinkverse.user.enums.ClaimStatusEnum;
import com.thinkverse.user.enums.IdentityClaimStatus;
import com.thinkverse.user.enums.RoleEnum;
import com.thinkverse.user.mapper.IdentityClaimMapper;
import com.thinkverse.user.mapper.UserMapper;
import com.thinkverse.user.service.IdentityService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 简化版身份认证流程：
 * - 提交申请时创建 IdentityClaim，状态 PENDING_EMAIL_VERIFICATION
 * - 验证邮箱后设置为 AUDITING
 * - 管理员审核设置 APPROVED/REJECTED；若 APPROVED 则更新 user.role -> EXPERT
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class IdentityServiceImpl implements IdentityService {

    private final IdentityClaimMapper claimMapper;
    private final UserMapper userMapper;

    @Override
    @Transactional
    public IdentityClaim submitClaim(Long userId, IdentityClaimRequestDTO request) {
        IdentityClaim c = new IdentityClaim();
        c.setUserId(userId);
        c.setOfficialEmail(request.getOfficialEmail());
        c.setInstitution(request.getInstitution());
        c.setResearchField(request.getResearchField());
        c.setPersonalHomepage(request.getPersonalHomepage());
        // 将 proofFiles 转为 JSON 字符串（简化）
        if (request.getProofFiles() != null) {
            c.setProofFiles(request.getProofFiles().toString());
        }
        c.setStatus(IdentityClaimStatus.PENDING_EMAIL_VERIFICATION);
        c.setCreatedAt(LocalDateTime.now());
        c.setUpdatedAt(LocalDateTime.now());
        claimMapper.insert(c);
        // TODO: 发送邮件并包含验证链接（token + applicationId）
        log.info("用户 {} 提交科研身份申请 {}", userId, c.getId());
        return c;
    }

    @Override
    @Transactional
    public void verifyEmailToken(Long applicationId, String token) {
        // token 验证流程可通过 verification_codes 或独立 token store 实现，简化为直接更新状态
        IdentityClaim c = claimMapper.selectById(applicationId);
        if (c == null) throw new RuntimeException("申请不存在");
        c.setStatus(IdentityClaimStatus.AUDITING);
        c.setUpdatedAt(LocalDateTime.now());
        claimMapper.updateById(c);
    }

    @Override
    public PagedResult<IdentityClaim> listMyClaims(Long userId) {
        QueryWrapper<IdentityClaim> qw = new QueryWrapper<>();
        qw.eq("user_id", userId).orderByDesc("created_at");
        List<IdentityClaim> list = claimMapper.selectList(qw);
        return new PagedResult<>(list.size(), list);
    }

    @Override
    public PagedResult<IdentityClaim> listAllClaims(int page, int size) {
        Page<IdentityClaim> p = new Page<>(page, size);
        Page<IdentityClaim> res = claimMapper.selectPage(p, new QueryWrapper<IdentityClaim>().orderByDesc("created_at"));
        return new PagedResult<>(res.getTotal(), res.getRecords());
    }

    @Override
    @Transactional
    public void auditClaim(Long adminUserId, Long applicationId, String auditStatus, String auditMessage) {
        IdentityClaim c = claimMapper.selectById(applicationId);
        if (c == null) throw new RuntimeException("申请不存在");
        if (!"APPROVED".equalsIgnoreCase(auditStatus) && !"REJECTED".equalsIgnoreCase(auditStatus)) {
            throw new RuntimeException("无效的审核状态");
        }
        if ("APPROVED".equalsIgnoreCase(auditStatus)) {
            c.setStatus(IdentityClaimStatus.APPROVED);
            // 升级 user role
            User u = userMapper.selectById(c.getUserId());
            if (u != null) {
                u.setRole(RoleEnum.EXPERT);
                u.setClaimStatus(ClaimStatusEnum.VERIFIED);
                u.setUpdatedAt(LocalDateTime.now());
                userMapper.updateById(u);
            }
        } else {
            c.setStatus(IdentityClaimStatus.REJECTED);
            User u = userMapper.selectById(c.getUserId());
            if (u != null) {
                u.setClaimStatus(ClaimStatusEnum.REJECTED);
                u.setUpdatedAt(LocalDateTime.now());
                userMapper.updateById(u);
            }
        }
        c.setAuditMessage(auditMessage);
        c.setUpdatedAt(LocalDateTime.now());
        claimMapper.updateById(c);
    }
}
